/*  This file is part of Real Time Digital Audio Processing library.
 *  Copyright (C) 2008 - Emilio Monti - emilmont@gmail.com
 *
 *  Real Time Digital Audio Processing library is free software: you can
 *  redistribute it and/or modify it under the terms of the GNU General
 *  Public License as published by the Free Software Foundation, either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  Real Time Digital Audio Processing library is distributed in the hope
 *  that it will be useful, but WITHOUT ANY WARRANTY; without even the
 *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Real Time Audio Processing library.
 *  If not, see <http://www.gnu.org/licenses/>.
 */
#include <string.h>

#include "VAD.h"

/**
 * First basic implementation.
 **/
VAD::VAD(unsigned long framesPerBuffer, unsigned int sampleRate, float activity_threshold, float hangover_time_s, RMS* rms) {
    sprintf(descr, "[=] VAD activity_threshold:(%0.2f)\n", activity_threshold);
    activity_threshold = activity_threshold;
    hangover_buffers = ((float)sampleRate*hangover_time_s)/(float)framesPerBuffer;
    this->rms = rms;

    active = false;
    hangCount = 0;
    word_index = 0;
}

void VAD::processSignal(float* signal, unsigned long length) {
    if (!active) {
        if (rms->getValue() > activity_threshold) {
            printf("<SPEAK index=\"%u\">\n", word_index++);
            active = true;
            hangCount = hangover_buffers;
        }
    } else {
        if (hangCount-- < 0) {
            active = false;
            printf("</SPEAK>\n\n");
        }
    }
}

Parrot::Parrot(float delay_s, unsigned long framesPerBuffer, unsigned int sampleRate, float activity_threshold, float hangover_time_s, RMS* rms):
    VAD(framesPerBuffer, sampleRate, activity_threshold, hangover_time_s, rms) {
    memory_index = 0;
    delay_samples = delay_s * (float)sampleRate;
    delay_index = 0;
}

void Parrot::processSignal(float* signal, unsigned long length) {
    if (!active) {
        if (rms->getValue() > activity_threshold) {
            /* START SPEAK */
            printf("<SPEAK index=\"%u\">\n", word_index++);
            active = true;
            hangCount = hangover_buffers;
            memory_index = 0;
        } else {
            memset(signal, 0, sizeof(float)*length);
            for (unsigned int i=0; i<length; i++) {
                /* DELAY AND SPEAK REPEAT */
                if (delay_index++ > delay_samples) {
                    if (memory_index >= PARROT_MEMORY)
                        break;
                    signal[i] = memory[memory_index];
                    memory_index++;
                }
            }
        }
    }

    if (active) {
        if (hangCount-- < 0) {
            memset(signal, 0, sizeof(float)*length);

            /* END SPEAK */
            active = false;
            printf("</SPEAK>\n\n");
            memory_index = 0;
            delay_index = 0;
        } else {
            /* SPEAK IN PROGRESS */
            for (unsigned int i=0; i<length; i++) {
                if (memory_index < PARROT_MEMORY) {
                    memory[memory_index] = signal[i];
                    memory_index++;
                }
                signal[i] = 0;
            }
        }
    }
}
